﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Als.Common.Image
{
    public class Captcha
    {
        #region 验证码配置

        public static int VcodeLength = 4;
        //产生图片 宽度：_WIDTH, 高度：_HEIGHT
        public static int Width = 80, Height = 35;
        //字体集
        public static string[] FontFamIly = { "Arial", "Avant Garde", "Calibri", "Candara", "Consolas", "Futura", "Helvetica", "Tahoma" };
        //字体大小集
        public static int[] FontSize = { 13, 14, 15, 16, 17, 18 };
        //前景字体颜色集1
        public static Color[] ColorFace = { Color.FromArgb(255, 87, 34), Color.FromArgb(109, 107, 103), Color.FromArgb(95, 184, 120), Color.FromArgb(109, 107, 103) };
        //前景字体颜色集2
        public static Color[] ColorFace2 = { Color.FromArgb(109, 107, 103), Color.FromArgb(30, 159, 255), Color.FromArgb(109, 107, 103), Color.FromArgb(247, 184, 36) };
        //单一颜色
        public static Color OneColorFace = Color.FromArgb(255, 87, 34);
        //109,108,108
        public static Color OneColorFacemx = Color.FromArgb(109, 108, 108);
        //背景颜色集
        public static Color[] ColorBackground = { Color.FromArgb(47, 64, 86), Color.FromArgb(47, 64, 86), Color.FromArgb(47, 64, 86), Color.FromArgb(47, 64, 86) };
        //单一颜色
        public static Color OneColorBackground = Color.FromArgb(47, 64, 86);
        //文本布局信息
        public static StringFormat DlFormat = new StringFormat(StringFormatFlags.NoClip);
        //左右旋转角度
        public static int Angle = 36;

        #endregion

        #region 获取验证码
        /// <summary>
        /// 获取验证码
        /// </summary>
        /// <param name="codeCount">验证码位数</param>
        /// <returns>返回字符串</returns>
        public static string GetCheckCode(int codeCount)
        {
            var allChar = "1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,T,U,W,X,Y,Z";
            var allCharArray = allChar.Split(',');
            var randomCode = "";
            var temp = -1;
            var rand = new Random();
            for (int i = 0; i < codeCount; i++)
            {
                if (temp != -1)
                {
                    rand = new Random(i * temp * ((int)DateTime.Now.Ticks));
                }
                int t = rand.Next(32);
                if (temp == t)
                {
                    return GetCheckCode(codeCount);
                }
                temp = t;
                randomCode += allCharArray[t];
            }
            return randomCode;
        }
        #endregion

        #region 根据验证码输出图片流
        /// <summary>
        /// 根据验证码输出图片
        /// </summary>
        /// <param name="code">验证码字符串</param>
        /// <returns>返回图片</returns>
        public static MemoryStream CreateImage(string code)
        {
            DlFormat.Alignment = StringAlignment.Center;
            DlFormat.LineAlignment = StringAlignment.Center;
            var tick = DateTime.Now.Ticks;
            var rnd = new Random((int)(tick & 0xffffffffL) | (int)(tick >> 32));
            using (var img = new Bitmap(Width, Height))
            {
                using (var g = Graphics.FromImage(img))
                {
                    g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
                    var dot = new Point(18, 18);
                    // 定义一个无干扰线区间和一个起始位置
                    int nor = rnd.Next(50), rsta = rnd.Next(120);
                    // 绘制干扰正弦曲线 M:曲线平折度, D:Y轴常量 V:X轴焦距
                    int m = rnd.Next(10) + 5, D = rnd.Next(10) + 5, V = rnd.Next(5) + 1;
                    var colorIndex = rnd.Next(4);
                    var pxX = 0.0F;
                    var pxY = Convert.ToSingle(m * Math.Sin(V * pxX * Math.PI / 180) + D);
                    //填充背景
                    //g.Clear(ColorBackground[Rnd.Next(4)]);
                    g.Clear(OneColorBackground);

                    //前景刷子 //背景刷子
                    using (Brush brushFace = new SolidBrush(OneColorFace))
                    {
                        //初始化光标的开始位置
                        g.TranslateTransform(-5, 3);

                        #region 绘制校验码字符串
                        foreach (char t in code)
                        {
                            //随机旋转 角度
                            var angle = rnd.Next(-Angle, Angle);
                            //移动光标到指定位置
                            g.TranslateTransform(dot.X, dot.Y);
                            //旋转
                            g.RotateTransform(angle);

                            //初始化字体
                            using (var font = new Font(FontFamIly[rnd.Next(0, 8)], FontSize[rnd.Next(0, 6)]))
                            {
                                var brush = new System.Drawing.Drawing2D.LinearGradientBrush(new Rectangle(0, 0, Width, Height), ColorFace[colorIndex], ColorFace2[colorIndex], 1.2f, true);
                                //绘制
                                g.DrawString(t.ToString(), font, brush, 1, 1, DlFormat);
                            }
                            //反转
                            g.RotateTransform(-angle);
                            //重新定位光标位置
                            g.TranslateTransform(-2, -dot.Y);
                        }
                        #endregion
                    }
                }
                using (var ms = new MemoryStream())
                {
                    img.Save(ms, ImageFormat.Png);
                    ms.Flush();
                    return ms;
                }
            }
        }
        #endregion
    }
}
